package com.jh.tools.api.manager;


import android.support.annotation.NonNull;

import com.apkfuns.logutils.LogUtils;
import com.facebook.stetho.okhttp3.BuildConfig;
import com.facebook.stetho.okhttp3.StethoInterceptor;
import com.jh.tools.api.ApiService;
import com.jh.tools.base.BaseApp;
import com.jh.tools.common.http.HttpUrlManage;
import com.jh.tools.common.http.networke.NetWorkUtils;

import java.io.File;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.UnsupportedCharsetException;
import java.util.List;
import java.util.concurrent.TimeUnit;

import okhttp3.Cache;
import okhttp3.CacheControl;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.Interceptor;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import okhttp3.logging.HttpLoggingInterceptor;
import okio.Buffer;
import okio.BufferedSource;
import retrofit2.Retrofit;
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
import retrofit2.converter.jackson.JacksonConverterFactory;

/**
 * ClassName: RetrofitManager<p>
 * Fuction: Retrofit请求管理类<p>
 * CreateDate:2016/2/13 20:34<p>
 * UpdateUser:<p>
 * UpdateDate:<p>
 */
public class RetrofitManager {

    //设缓存有效期为两天
    private static final long CACHE_STALE_SEC = 60 * 60 * 24 * 2;
    //查询缓存的Cache-Control设置，为if-only-cache时只查询缓存而不会请求服务器，max-stale可以配合设置缓存失效时间
    private static final String CACHE_CONTROL_CACHE = "only-if-cached, max-stale=" + CACHE_STALE_SEC;
    //查询网络的Cache-Control设置，头部Cache-Control设为maxd-age=0时则不会使用缓存而请求服务器
    private static final String CACHE_CONTROL_NETWORK = "max-age=0";

    private final ApiService mApiService;
    private static volatile OkHttpClient mOkHttpClient;

    /**
     * 创建实例
     *
     * @return 实例
     */
    public static HttpUrlManage builder(String urlName) {
        new RetrofitManager(urlName);
        return HttpUrlManage.HttpUrlManage();
    }

    private RetrofitManager(String baseUrl) {

        initOkHttpClient();

        Retrofit retrofit = new Retrofit.Builder().baseUrl(baseUrl).client(mOkHttpClient)
                .addConverterFactory(JacksonConverterFactory.create())
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
        mApiService = retrofit.create(ApiService.class);
        HttpUrlManage.HttpUrlManage().setmApiService(this,mApiService);
    }

    // 配置OkHttpClient
    private void initOkHttpClient() {
        if (mOkHttpClient == null) {

            synchronized (RetrofitManager.class) {

                if (mOkHttpClient == null) {
                    LogUtils.e("初始化mOkHttpClient");
                    // 因为BaseUrl不同所以这里Retrofit不为静态，但是OkHttpClient配置是一样的,静态创建一次即可

                    // 指定缓存路径,缓存大小100Mb
                    Cache cache = new Cache(new File(BaseApp.getmContext().getCacheDir(), "HttpCache"),
                            1024 * 1024 * 100);
                    OkHttpClient.Builder okHttpBuilder = new OkHttpClient.Builder();
                        okHttpBuilder.addNetworkInterceptor(new StethoInterceptor());// 浏览器查看网络请求拦截器
                        okHttpBuilder.addInterceptor( new HttpLoggingInterceptor( new HttpLoggingInterceptor.Logger() {
                            @Override
                            public void log(String message) {
                                LogUtils.i("OkHttp", message);
                            }
                        }).setLevel(HttpLoggingInterceptor.Level.BODY));//网络和日志拦截
                    okHttpBuilder.cache(cache)
                            .addNetworkInterceptor(mRewriteCacheControlInterceptor)//网络读写缓存拦截器
                            .addInterceptor(mRewriteCacheControlInterceptor)//添加读写缓存拦截器
                            .addInterceptor(mLoggingInterceptor)// 设置请求消息拦截器
                            .retryOnConnectionFailure(true)//尝试进香重新连接
                            .connectTimeout(OkHttpHandle.TIME_OUT, TimeUnit.SECONDS)// 设置连接时间
                            .readTimeout(OkHttpHandle.TIME_OUT, TimeUnit.SECONDS)//设置读写时间
                            .writeTimeout(OkHttpHandle.TIME_OUT, TimeUnit.SECONDS)//设置请求超时
                            .cookieJar(new CookiesManager());//cookie自动管理类
                    mOkHttpClient=okHttpBuilder.build();

                }
            }
        }
    }

    // 云端响应头拦截器，用来配置缓存策略
    private Interceptor mRewriteCacheControlInterceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();
            if (!NetWorkUtils.isConnectNet(BaseApp.getmContext())) {
                request = request.newBuilder().cacheControl(CacheControl.FORCE_CACHE).build();
                LogUtils.e("no network");
            }
            Response originalResponse = chain.proceed(request);

            if (NetWorkUtils.isConnectNet(BaseApp.getmContext())) {
                //有网的时候读接口上的@Headers里的配置，你可以在这里进行统一的设置
                String cacheControl = request.cacheControl().toString();
                return originalResponse.newBuilder().header("Cache-Control", cacheControl)
                        .removeHeader("Pragma").build();
            } else {
                return originalResponse.newBuilder()
                        .header("Cache-Control", "public, only-if-cached," + CACHE_STALE_SEC)
                        .removeHeader("Pragma").build();
            }
        }
    };

    // 打印返回的json数据拦截器
    private Interceptor mLoggingInterceptor = new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {

            final Request request = chain.request();

            final Response response = chain.proceed(request);
            LogUtils.i(request.url());
            final ResponseBody responseBody = response.body();
            final long contentLength = responseBody.contentLength();

            BufferedSource source = responseBody.source();
            source.request(Long.MAX_VALUE); // Buffer the entire body.
            Buffer buffer = source.buffer();

            Charset charset = Charset.forName("UTF-8");
            MediaType contentType = responseBody.contentType();
            if (contentType != null) {
                try {
                    charset = contentType.charset(charset);
                } catch (UnsupportedCharsetException e) {
                    LogUtils.e("");
                    LogUtils.e("Couldn't decode the response body; charset is likely malformed.");
                    return response;
                }
            }

            if (contentLength != 0) {
                LogUtils.v("--------------------------------------------开始打印返回数据----------------------------------------------------");
                LogUtils.json(buffer.clone().readString(charset));
                LogUtils.v("--------------------------------------------结束打印返回数据----------------------------------------------------");
            }

            return response;
        }
    };


    /**
     * 根据网络状况获取缓存的策略
     *
     * @return
     */
    @NonNull
    public String getCacheControl() {
        return NetWorkUtils.isConnectNet(BaseApp.getmContext()) ? CACHE_CONTROL_NETWORK : CACHE_CONTROL_CACHE;
    }


}
